package cn.tianyigps.tianyigpsbatterylockalarm.hanlder;

import cn.tianyigps.tianyigpsbatterylockalarm.dto.BatteryAlarmResponse;
import cn.tianyigps.tianyigpskafka.task.bean.Task;
import cn.tianyigps.tianyigpskafka.task.manger.TaskManger;
import cn.tianyigps.tianyigpspublic.bean.EquipmentModel;
import cn.tianyigps.tianyigpspublic.enums.LocationType;
import cn.tianyigps.tianyigpspublic.util.LocationalUtils;
import cn.tianyigps.tianyigpspublic.util.MapTransformUtils;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.geo.Point;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.Map;


/**
 * @Author: WEI.YUAN
 * @Descirption:
 * @Date: 2019/4/15_11:10
 */
@Component
@Slf4j
public class BatteryRuleHandler {
    private static ObjectMapper OM = new ObjectMapper();

    @Autowired
    RedisTemplate redisTemplate;
    @Autowired
    TaskManger taskManger;

    public static JavaType getCollectionType(Class<?> collectionClass, Class<?>... elementClasses) {
        ObjectMapper objectMapper = new ObjectMapper();
        return objectMapper.getTypeFactory().constructParametricType(collectionClass, elementClasses);
    }


    /**
     * 处理数据是否报警
     * @param task
     */
    public void BatteryAlarm(Task task) {
        //获取task中的eqckmodel
        EquipmentModel eqCheckModel = this.getEQCheckModel(task);
        if (eqCheckModel == null) {
            return;
        }
        //排除基站定位
        if (LocationType.BASE_LOC.getType().equals(eqCheckModel.getLocationType())) {
            return;
        }
        //规则为空无意义,返回
        Object object = redisTemplate.opsForValue().get(eqCheckModel.getEquipmentId() + "BatteryRule");

        if (object == null) {
            return;
        }
        //规则点task
        Task previousTask = (Task) object;

        /* 报警过不再报警 */
        if (previousTask.getParams().containsKey("isAlarm") && previousTask.getParams().get("isAlarm").toString().equals("1")) {
            return;
        }
        Map<String, Object> previousMap = new HashMap<>();
        try {

            String json1 = OM.writeValueAsString(previousTask.getParams());
            previousMap = OM.readValue(json1, HashMap.class);
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage()+"电瓶车规则序列化失败");
            return;
        }
        //高德坐标转百度坐标
        Double eqLongitude=eqCheckModel.getGpsLongitude();
        Double eqLatitude=eqCheckModel.getGpsLatitude();
        Point point=MapTransformUtils.gcj02tobd09(eqLongitude,eqLatitude);

        Double distance=0.0;
        //计算点到规则点的距离
        try{
            distance= LocationalUtils.calcDistance(Double.valueOf(previousMap.get("longitude").toString()),
                    Double.valueOf(previousMap.get("latitude").toString()), point.getX(), point.getY());
        }catch(Exception e){
            e.printStackTrace();
            log.error("不规则点或计算点之间的距离出错:{}",e);
            return;
        }

        //半径
        Double radius = Double.valueOf(previousMap.get("radius").toString());
        //小于半径不报警
        if (distance < radius) {
            return;
        }
        //报警的时候吧规则isAlarm设置为1
        previousMap.put("isAlarm", "1");
        previousTask.setParams(previousMap);
        redisTemplate.opsForValue().set((eqCheckModel.getEquipmentId() + "BatteryRule"), previousTask);


        Task nextTask = previousTask.getNextTask();
        Map<String, Object> nextMap = nextTask.getParams();

        BatteryAlarmResponse batteryAlarmResponse = new BatteryAlarmResponse();
        batteryAlarmResponse.setEquipmentId(eqCheckModel.getEquipmentId())
                .setLongitude(point.getX())
                .setLatitude(point.getY())
                .setDistance(distance)
                .setAlarmStartTime(eqCheckModel.getLocateTime())
                .setTaskId(previousTask.getId())
                .setLocational(LocationalUtils.getLocational(point.getX(), point.getY()));
        nextMap.put("batteryAlarmResponse", batteryAlarmResponse);
        nextTask.setParams(nextMap);
        nextTask.setId(task.getId());
        taskManger.distributeTask(nextTask);
    }

    public EquipmentModel getEQCheckModel(Task task) {
        String json = "";
        EquipmentModel eqCheckModel = null;
        try {
            json = OM.writeValueAsString(task.getParams().get("equipmentModel"));
            JavaType javaType =getCollectionType(EquipmentModel.class);
            eqCheckModel = OM.readValue(json, javaType);
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage() + "EquipmentCheckModel序列化失败");
            return null;
        }

        //设备号id,经纬度，时间不能为空
        if (StringUtils.isEmpty(eqCheckModel.getEquipmentId())
                || StringUtils.isEmpty(eqCheckModel.getGpsLongitude())
                || StringUtils.isEmpty(eqCheckModel.getGpsLatitude())
                || eqCheckModel.getLocateTime() == null) {
            return null;
        }
        return eqCheckModel;
    }

}
